package post_to_in_pkg.parser;
import post_to_in_pkg.lexer.Token;

public class OP_Keyword extends Token{
	int op_num;
	Type returnType;
	//boolean is_stop_after_this;
	boolean is_enabled;
	boolean is_variable_parameter=false;
	int arg_list_count=1;
	//int argc[]=null; //used to record the argc in an argument list

	private String function_description="";
	
	/*
	 * 	"OP_KEYWORD":{
		"signature":
		"argc":
		"return":
		"is_enabled":
		"is_variable_parameter":
		"function_description":
		
		}*/
	
	
	public OP_Keyword(String s,int arg_op_num, Type type,boolean enable,
			String description) {
		super(s,post_to_in_pkg.lexer.Tag.OP_KEY);
		op_num=arg_op_num;
		returnType =type;
		//is_stop_after_this=is_stop;
		is_enabled=enable;
		function_description=description;
	}


	public OP_Keyword(String s,Type type,boolean enable, boolean is_var_para
		,int argc, String description){
		super(s,post_to_in_pkg.lexer.Tag.OP_KEY);
		//op_num=arg_op_num;
		returnType =type;
		//is_stop_after_this=is_stop;
		is_enabled=enable;
		is_variable_parameter=is_var_para;
		arg_list_count=argc;
		function_description=description;
	}
	
	public String getDescription() {
		return function_description;
	}
	
	public int getArgumentListCount(){
		return arg_list_count;
	}
	
	public void setDescription(String desc) {
		function_description=desc;
	}
	
	public Type getReturnType() {
		return returnType;
	}
	
	public int getArgmentNumber() {
		return op_num;
	}
	
	public boolean isVariableParameter(){
		return is_variable_parameter;
	}

	public boolean isEnable(){
		return is_enabled;
	}

	public void setEnable(boolean sig){
		is_enabled=sig;
	}
	// public boolean isStopAfterThis(){
	// 	return is_stop_after_this;
	// }

	public static final OP_Keyword 

			
			//Constants
			/*
			Word			Opcode	Hex			Input		Output			Description
			OP_0, OP_FALSE	0		0x00		Nothing.	(empty value)	An empty array of bytes is pushed onto the stack. (This is not a no-op: an item is added to the stack.)
			N/A				1-75	0x01-0x4b	(special)	data			The next opcode bytes is data to be pushed onto the stack
			OP_PUSHDATA1	76		0x4c		(special)	data			The next byte contains the number of bytes to be pushed onto the stack.
			OP_PUSHDATA2	77		0x4d		(special)	data			The next two bytes contain the number of bytes to be pushed onto the stack in little endian order.
			OP_PUSHDATA4	78		0x4e		(special)	data			The next four bytes contain the number of bytes to be pushed onto the stack in little endian order.
			OP_1NEGATE		79		0x4f		Nothing.	-1				The number -1 is pushed onto the stack.
			OP_1, OP_TRUE	81		0x51		Nothing.	1				The number 1 is pushed onto the stack.
			OP_2-OP_16		82-96	0x52-0x60	Nothing.	2-16			The number in the word name (2-16) is pushed onto the stack.
			*/
//			TRUE=new OP_Keyword("TRUE",0,Type.BOOL,true,false,"Same as OP_TURE"),
//			FALSE=new OP_Keyword("FALSE",0,Type.BOOL,true,false,"Same as OP_FALSE"),
//			OP_TRUE=new OP_Keyword("OP_TRUE",0,Type.BOOL,true,false,"An empty array of bytes is pushed onto the stack. (This is not a no-op: an item is added to the stack.)"),
//			OP_FALSE=new OP_Keyword("OP_FALSE",0,Type.BOOL,true,false,"An empty array of bytes is pushed onto the stack. (This is not a no-op: an item is added to the stack.)"),
			//Flow controls
			/*

			Word		Opcode		Hex			Input			Output  		Description
			OP_NOP		97			0x61		Nothing			nothing 		Does nothing.
		   #OP_IF		99			0x63		<expression> 	if [statements] [else [statements]]* endif	If the top stack value is not False, the statements are executed. The top stack value is removed.
		   #OP_NOTIF	100			0x64		<expression> 	notif [statements] [else [statements]]* endif	If the top stack value is False, the statements are executed. The top stack value is removed.
			#OP_ELSE		103			0x67		<expression> 	if [statements] [else [statements]]* endif	If the preceding OP_IF or OP_NOTIF or OP_ELSE was not executed then these statements are and if the preceding OP_IF or OP_NOTIF or OP_ELSE was executed then these statements are not.
			#OP_ENDIF	104			0x68		<expression> 	if [statements] [else [statements]]* endif	Ends an if/else block. All blocks must end, or the transaction is invalid. An OP_ENDIF without OP_IF earlier is also invalid.
			OP_VERIFY	105			0x69		True / false	Nothing / fail	Marks transaction as invalid if top stack value is not true. The top stack value is removed.
			OP_RETURN	106			0x6a		Nothing	fail	Marks transaction as invalid. Since bitcoin 0.9, a standard way of attaching extra data to transactions is to add a zero-value output with a scriptPubKey consisting of OP_RETURN followed by data. Such outputs are provably unspendable and specially discarded from storage in the UTXO set, reducing their cost to the network. Since 0.12, standard relay rules allow a single output with OP_RETURN, that contains any sequence of push statements (or OP_RESERVED[1]) after the OP_RETURN provided the total scriptPubKey length is at most 83 bytes.
			*/
			OP_VERIFY=new OP_Keyword("OP_VERIFY",1,Type.VOID,true,"Marks transaction as invalid if top stack value is not true. The top stack value is removed."),
			//OP_RETURN=new OP_Keyword("OP_RETURN",0,Type.VOID,true,true,"Marks transaction as invalid. Since bitcoin 0.9, a standard way of attaching extra data to transactions is to add a zero-value output with a scriptPubKey consisting of OP_RETURN followed by data. Such outputs are provably unspendable and specially discarded from storage in the UTXO set, reducing their cost to the network. Since 0.12, standard relay rules allow a single output with OP_RETURN, that contains any sequence of push statements (or OP_RESERVED[1]) after the OP_RETURN provided the total scriptPubKey length is at most 83 bytes."),


			//stack 
			/*
			
			Word			Opcode		Hex			Input			Output			Description
			OP_TOALTSTACK	107	0x6b	x1	(alt)x1	Puts the input onto the top of the alt stack. Removes it from the main stack.
			OP_FROMALTSTACK	108	0x6c	(alt)x1	x1	Puts the input onto the top of the main stack. Removes it from the alt stack.
			OP_IFDUP		115	0x73	x	x / x x	If the top stack value is not 0, duplicate it.
			OP_DEPTH		116	0x74	Nothing	<Stack size>	Puts the number of stack items onto the stack.
			OP_DROP			117	0x75	x	Nothing	Removes the top stack item.
			OP_DUP			118	0x76	x	x x	Duplicates the top stack item.
			OP_NIP			119	0x77	x1 x2	x2	Removes the second-to-top stack item.
			OP_OVER			120	0x78	x1 x2	x1 x2 x1	Copies the second-to-top stack item to the top.
			OP_PICK			121	0x79	xn ... x2 x1 x0 <n>	xn ... x2 x1 x0 xn	The item n back in the stack is copied to the top.
			OP_ROLL			122	0x7a	xn ... x2 x1 x0 <n>	... x2 x1 x0 xn	The item n back in the stack is moved to the top.
			OP_ROT			123	0x7b	x1 x2 x3	x2 x3 x1	The top three items on the stack are rotated to the left.
			OP_SWAP			124	0x7c	x1 x2	x2 x1	The top two items on the stack are swapped.
			OP_TUCK			125	0x7d	x1 x2	x2 x1 x2	The item at the top of the stack is copied and inserted before the second-to-top item.
			OP_2DROP		109	0x6d	x1 x2	Nothing	Removes the top two stack items.
			OP_2DUP			110	0x6e	x1 x2	x1 x2 x1 x2	Duplicates the top two stack items.
			OP_3DUP			111	0x6f	x1 x2 x3	x1 x2 x3 x1 x2 x3	Duplicates the top three stack items.
			OP_2OVER		112	0x70	x1 x2 x3 x4	x1 x2 x3 x4 x1 x2	Copies the pair of items two spaces back in the stack to the front.
			OP_2ROT			113	0x71	x1 x2 x3 x4 x5 x6	x3 x4 x5 x6 x1 x2	The fifth and sixth items back are moved to the top of the stack.
			OP_2SWAP		114	0x72	x1 x2 x3 x4	x3 x4 x1 x2	Swaps the top two pairs of items
			*/

			OP_DROP=new OP_Keyword("OP_DROP",1,Type.VOID,true,"Removes the top stack item."),
			OP_DUP=new OP_Keyword("OP_DUP",1,Type.TEMPVAR,true,"Duplicates the top stack item."),

			//Bitwise logic
			/*
			OP_EQUAL		135	0x87	x1 x2	True / false	Returns 1 if the inputs are exactly equal, 0 otherwise.
			OP_EQUALVERIFY	136	0x88	x1 x2	Nothing / fail	Same as OP_EQUAL, but runs OP_VERIFY afterward.
			*/
			OP_EQUAL=new OP_Keyword("OP_EQUAL",2,Type.BOOL,true,"Returns 1 if the inputs are exactly equal, 0 otherwise."),
			OP_EQUALVERIFY=new OP_Keyword("OP_EQUALVERIFY",2,Type.VOID,true,"Same as OP_EQUAL, but runs OP_VERIFY afterward."),

			//Arithmetic
			/*
			Word					Opcode	Hex		Input	Output	Description
			OP_1ADD					139		0x8b	in		out	1 is added to the input.
			OP_1SUB					140		0x8c	in		out	1 is subtracted from the input.
			OP_2MUL					141		0x8d	in		out	The input is multiplied by 2. disabled.
			OP_2DIV					142		0x8e	in		out	The input is divided by 2. disabled.
			OP_NEGATE				143		0x8f	in		out	The sign of the input is flipped.
			OP_ABS					144		0x90	in		out	The input is made positive.
			OP_NOT					145		0x91	in		out	If the input is 0 or 1, it is flipped. Otherwise the output will be 0.
			OP_0NOTEQUAL			146		0x92	in		out	Returns 0 if the input is 0. 1 otherwise.
			OP_ADD					147		0x93	a b		out	a is added to b.
			OP_SUB					148		0x94	a b		out	b is subtracted from a.
			OP_MUL					149		0x95	a b		out	a is multiplied by b. disabled.
			OP_DIV					150		0x96	a b		out	a is divided by b. disabled.
			OP_MOD					151		0x97	a b		out	Returns the remainder after dividing a by b. disabled.
			OP_LSHIFT				152		0x98	a b		out	Shifts a left b bits, preserving sign. disabled.
			OP_RSHIFT				153		0x99	a b		out	Shifts a right b bits, preserving sign. disabled.
			OP_BOOLAND				154		0x9a	a b		out	If both a and b are not 0, the output is 1. Otherwise 0.
			OP_BOOLOR				155		0x9b	a b		out	If a or b is not 0, the output is 1. Otherwise 0.
			OP_NUMEQUAL				156		0x9c	a b		out	Returns 1 if the numbers are equal, 0 otherwise.
			OP_NUMEQUALVERIFY		157		0x9d	a b		Nothing / fail	Same as OP_NUMEQUAL, but runs OP_VERIFY afterward.
			OP_NUMNOTEQUAL			158		0x9e	a b		out	Returns 1 if the numbers are not equal, 0 otherwise.
			OP_LESSTHAN				159		0x9f	a b		out	Returns 1 if a is less than b, 0 otherwise.
			OP_GREATERTHAN			160		0xa0	a b		out	Returns 1 if a is greater than b, 0 otherwise.
			OP_LESSTHANOREQUAL		161		0xa1	a b		out	Returns 1 if a is less than or equal to b, 0 otherwise.
			OP_GREATERTHANOREQUAL	162		0xa2	a b		out	Returns 1 if a is greater than or equal to b, 0 otherwise.
			OP_MIN					163		0xa3	a b		out	Returns the smaller of a and b.
			OP_MAX					164		0xa4	a b		out	Returns the larger of a and b.
			OP_WITHIN				165		0xa5	x min maxout	Returns 1 if x is within the specified range (left-inclusive), 0 otherwise.
			*/
			OP_ADD=new OP_Keyword("OP_ADD",2,Type.TEMPVAR,true,"just as its name implies"),
			OP_SUB=new OP_Keyword("OP_SUB",2,Type.TEMPVAR,true,"just as its name implies"),
			OP_MUL=new OP_Keyword("OP_MUL",2,Type.TEMPVAR,true,"just as its name implies"),
			OP_DIV=new OP_Keyword("OP_DIV",2,Type.TEMPVAR,true,"just as its name implies"),

	
			//Crypto
			/*

			Word					Opcode		Hex	Input	Output	Description
			OP_RIPEMD160			166	0xa6	in	hash	The input is hashed using RIPEMD-160.
			OP_SHA1					167	0xa7	in	hash	The input is hashed using SHA-1.
			OP_SHA256				168	0xa8	in	hash	The input is hashed using SHA-256.
			OP_HASH160				169	0xa9	in	hash	The input is hashed twice: first with SHA-256 and then with RIPEMD-160.
			OP_HASH256				170	0xaa	in	hash	The input is hashed two times with SHA-256.
			OP_CODESEPARATOR		171	0xab	Nothing	Nothing	All of the signature checking words will only match signatures to the data after the most recently-executed OP_CODESEPARATOR.
			OP_CHECKSIG				172	0xac	sig pubkey	True / false	The entire transaction's outputs, inputs, and script (from the most recently-executed OP_CODESEPARATOR to the end) are hashed. The signature used by OP_CHECKSIG must be a valid signature for this hash and public key. If it is, 1 is returned, 0 otherwise.
			OP_CHECKSIGVERIFY		173	0xad	sig pubkey	Nothing / fail	Same as OP_CHECKSIG, but OP_VERIFY is executed afterward.
			OP_CHECKMULTISIG		174	0xae	x sig1 sig2 ... <number of signatures> pub1 pub2 <number of public keys>	True / False	Compares the first signature against each public key until it finds an ECDSA match. Starting with the subsequent public key, it compares the second signature against each remaining public key until it finds an ECDSA match. The process is repeated until all signatures have been checked or not enough public keys remain to produce a successful result. All signatures need to match a public key. Because public keys are not checked again if they fail any signature comparison, signatures must be placed in the scriptSig using the same order as their corresponding public keys were placed in the scriptPubKey or redeemScript. If all signatures are valid, 1 is returned, 0 otherwise. Due to a bug, one extra unused value is removed from the stack.
			OP_CHECKMULTISIGVERIFY	175	0xaf	x sig1 sig2 ... <number of signatures> pub1 pub2 ... <number of public keys>	Nothing / fail	Same as OP_CHECKMULTISIG, but OP_VERIFY is executed afterward.
			*/
			OP_RIPEMD160=new OP_Keyword("OP_RIPEMD160",1,Type.TEMPVAR,true,"The input is hashed using RIPEMD-160"),
			OP_SHA1=new OP_Keyword("OP_SHA1",1,Type.TEMPVAR,true,"The input is hashed using SHA-1"),
			OP_SHA256=new OP_Keyword("OP_SHA256",1,Type.TEMPVAR,true,"The input is hashed using SHA-256"),
			OP_HASH160=new OP_Keyword("OP_HASH160",1,Type.TEMPVAR,true,"The input is hashed twice: first with SHA-256 and then with RIPEMD-160."),
			OP_HASH256=new OP_Keyword("OP_HASH256",1,Type.TEMPVAR,true,"The input is hashed two times with SHA-256."),
			//OP_CODESEPARATOR=
			OP_CHECKSIG=new OP_Keyword("OP_CHECKSIG",2,Type.BOOL,true,"The entire transaction's outputs, inputs, and script (from the most recently-executed OP_CODESEPARATOR to the end) are hashed. The signature used by OP_CHECKSIG must be a valid signature for this hash and public key. If it is, 1 is returned, 0 otherwise."),
			OP_CHECKSIGVERIFY=new OP_Keyword("OP_CHECKSIGVERIFY",2,Type.VOID,true,"Same as OP_CHECKSIG, but OP_VERIFY is executed afterward."),
			OP_CHECKMULTISIG=new OP_Keyword("OP_CHECKMULTISIG",Type.BOOL,true,true,2,"Compares the first signature against each public key until it finds an ECDSA match. Starting with the subsequent public key, it compares the second signature against each remaining public key until it finds an ECDSA match. The process is repeated until all signatures have been checked or not enough public keys remain to produce a successful result. All signatures need to match a public key. Because public keys are not checked again if they fail any signature comparison, signatures must be placed in the scriptSig using the same order as their corresponding public keys were placed in the scriptPubKey or redeemScript. If all signatures are valid, 1 is returned, 0 otherwise. Due to a bug, one extra unused value is removed from the stack."),
			OP_CHECKMULTISIGVERIFY=new OP_Keyword("OP_CHECKMULTISIGVERIFY",Type.VOID,true,true,2,"Same as OP_CHECKMULTISIG, but OP_VERIFY is executed afterward."),



			//Locktime
			/*

			Word										Opcode	Hex		Input	Output		Description
			OP_CHECKLOCKTIMEVERIFY (previously OP_NOP2)	177		0xb1	x		x / fail	Marks transaction as invalid if the top stack item is greater than the transaction's nLockTime field, otherwise script evaluation continues as though an OP_NOP was executed. Transaction is also invalid if 1. the stack is empty; or 2. the top stack item is negative; or 3. the top stack item is greater than or equal to 500000000 while the transaction's nLockTime field is less than 500000000, or vice versa; or 4. the input's nSequence field is equal to 0xffffffff. The precise semantics are described in BIP 0065.
			OP_CHECKSEQUENCEVERIFY (previously OP_NOP3)	178		0xb2	x		x / fail	Marks transaction as invalid if the relative lock time of the input (enforced by BIP 0068 with nSequence) is not equal to or longer than the value of the top stack item. The precise semantics are described in BIP 0112.
			*/
			OP_CHECKLOCKTIMEVERIFY=new OP_Keyword("OP_CHECKLOCKTIMEVERIFY",2,Type.BOOL,true,"Marks transaction as invalid if the top stack item is greater than the transaction's nLockTime field, otherwise script evaluation continues as though an OP_NOP was executed. Transaction is also invalid if 1. the stack is empty; or 2. the top stack item is negative; or 3. the top stack item is greater than or equal to 500000000 while the transaction's nLockTime field is less than 500000000, or vice versa; or 4. the input's nSequence field is equal to 0xffffffff. The precise semantics are described in BIP 0065."),
			OP_CHECKSEQUENCEVERIFY=new OP_Keyword("OP_CHECKSEQUENCEVERIFY",1,Type.BOOL,true,
					 "Marks transaction as invalid if the relative lock time of the input (enforced by BIP 0068 with nSequence) "
					+"is not equal to or longer than the value of the top stack item. "
					+"The precise semantics are described in BIP 0112.");
			
}
